﻿#include "pch.h"

CTprgInfWrapper::CTprgInfWrapper()
{
    memset((void *)this, 0, sizeof(CTprgInfWrapper));
}

void CTprgInfWrapper::printSelf(char *captionUpper, int32_t)
{
    char caption[1024];
    sprintf(caption, "%s:%s", captionUpper, "CTprgInfWrapper");
    print4x(this, sizeof(CTprgInfWrapper), caption);
    if (this->head)
    {
        sprintf(caption, "%s:%s", captionUpper, "CTprgInfWrapper.head");
        print4x(this->head, this->size * this->len, caption);
    }
    if (this->num)
    {
        sprintf(caption, "%s:%s", captionUpper, "CTprgInfWrapper.num");
        print4x(this->num, sizeof(int32_t), caption);
    }
}

// sub_1001D060
CTprgInfWrapper *CTprgInfWrapper::init(TDLLTPRGINF *tprgInf)
{
    this->init_(tprgInf);
    this->setComplexEvent();
    this->sortData();
    return this;
};

// sub_1001DD40
CTprgInfWrapper *CTprgInfWrapper::init_(TDLLTPRGINF *tprgInf)
{
    this->head = (LPVOID)tprgInf->head;
    this->size = 16;
    this->len = tprgInf->len;
    this->tail = 0;
    this->needFreeHead = false;
    this->num = tprgInf->num;
    return this;
};

// sub_1001E7B3
int32_t CTprgInfWrapper::setComplexEvent()
{
    int32_t result;
    int32_t i;
    EVENT event;
    TDLLTPRGListItem *pHead = (TDLLTPRGListItem *)this->head;

    i = 0;
    for (result = this->getNum(); i < result; result = this->getNum())
    {
        event = pHead[i].event;
        if (event == BASE_TOGETHER || event == BASE_TAIL_TANGENT)
        {
            if (getNextEventCrossed((TDLLTPRGListItem *)this->head, i, PEAK_DELETE) >= 0)
            {
                pHead[i].event = (EVENT)(event + 24);
            }
            if (getNextEventCrossed((TDLLTPRGListItem *)this->head, i, BASE_LOCK) >= 0)
            {
                pHead[i].event = (EVENT)(event + 24);
            }
            if (event == BASE_TOGETHER)
            {
                if (getNextEventCrossed((TDLLTPRGListItem *)this->head, i, BASE_TAIL_TANGENT) >= 0)
                {
                    pHead[i].event = BASE_TOGETHER_;
                }
            }
            else if (getNextEventCrossed((TDLLTPRGListItem *)this->head, i, BASE_TOGETHER) >= 0)
            {
                pHead[i].event = BASE_TAIL_TANGENT_;
            }
        }
        ++i;
    }
    return result;
}

// sub_1001E8D3
int32_t CTprgInfWrapper::getNextEventCrossed(TDLLTPRGListItem *pHead, int32_t offset, EVENT event)
{
    int32_t i;
    int32_t ret;

    ret = -1;
    if (offset > 0)
    {
        for (i = offset - 1; i >= 0; --i)
        {
            if (pHead[i].event == event && isTimeCrossed(pHead[offset].ts, pHead[offset].te, pHead[i].ts, pHead[i].te))
            {
                return i;
            }
        }
    }
    return ret;
};

// sub_1001E982
int32_t CTprgInfWrapper::isTimeCrossed(double d1, double d2, double d3, double d4)
{
    if (d1 >= d3 && (d4 < 0.0000001 || d1 <= d4))
    {
        return true;
    }
    if (d2 >= 0.0000001 && d2 >= d3 && (d4 < 0.0000001 || d2 <= d4))
    {
        return true;
    }
    if (d3 >= d1 && (d1 < 0.0000001 || d3 <= d2))
    {
        return true;
    }
    return d4 >= 0.0000001 && d4 >= d1 && (d2 < 0.0000001 || d4 <= d2);
};

// sub_1001EA64
void CTprgInfWrapper::sortData()
{
    int32_t i, j;
    char Src[16];
    TDLLTPRGListItem *pHead = (TDLLTPRGListItem *)this->head;

    this->eCount = 0;
    //    j = 0;
    for (i = this->getNum(), j = 0; j < i; i = this->getNum())
    {
        if ((int32_t)pHead[j].event > 7 && (int32_t)pHead[j].event != 10 && (int32_t)pHead[j].event <= 31)
        {
            memcpy(Src, (const void *)&pHead[j], sizeof(Src));
            memmove((void *)&pHead[this->eCount + 1], (const void *)&pHead[this->eCount],
                    sizeof(TDLLTPRGListItem) * (j - this->eCount));
            memcpy((void *)&pHead[this->eCount], Src, sizeof(TDLLTPRGListItem));
            ++this->eCount;
        }
        ++j;
    }
    if (this->eCount > 0)
    {
        qsort(*(void **)this, this->eCount, sizeof(TDLLTPRGListItem), compareFloat);
    }
};

// sub_1001E78C
int32_t CTprgInfWrapper::clean()
{
    this->x7 = 0;
    this->x8 = 0;

    return this->clearIndex();
};

// sub_10024F50
int32_t CTprgInfWrapper::clearIndex()
{
    return this->setTail(0);
}

// sub_1001ECD9
int32_t CTprgInfWrapper::getPrgItemEventAndTsTe(int32_t idx, float *ts, float *te)
{
    TDLLTPRGListItem *pHead = (TDLLTPRGListItem *)this->head;
    if (idx < 0 || idx >= this->getNum())
    {
        return -1;
    }
    if (ts)
    {
        *ts = pHead[idx].ts;
    }
    if (te)
    {
        *te = pHead[idx].te;
    }
    return (int32_t)pHead[idx].event;
}
